const { src, dest, series, parallel, watch } = require('gulp')

const path = require('path')
const del = require('del')
const browserSync = require('browser-sync')
const bs = browserSync.create()

const { sass, babel, swig, imagemin, useref, if: gulp_if, uglify, cleanCss, htmlmin } = require('gulp-load-plugins')()

let config = {
  // 默认配置
  build: {
    src: 'src',
    dist: 'dist',
    temp: 'temp',
    public: 'public',
    paths: {
      styles: 'assets/styles/*.scss',
      scripts: 'assets/scripts/*.js',
      pages: '*.html',
      images: 'assets/images/**',
      fonts: 'assets/fonts/**'
    }
  }
}

try {
  config = Object.assign({}, config, require(path.join(process.cwd(), 'pages.config.js')))
} catch (e) {

}

const { data, build: { src: configSrc, dist, temp, public: configPublic, paths: { styles, scripts, pages, images, fonts }}} = config

// 删除指定目录文件
const clean = () => (
  del([dist, temp])
)

// 样式文件编译
const style = () => (
  src(styles, { base: configSrc, cwd: configSrc })
    .pipe(sass({ outputStyle: 'expanded' }))
    .pipe(dest(temp))
    .pipe(bs.reload({ stream: true }))
)
// 脚本文件编译
const script = () => (
  src(scripts, { base: configSrc, cwd: configSrc })
    .pipe(babel({ presets: [require('@babel/preset-env')] }))
    .pipe(dest(temp))
    .pipe(bs.reload({ stream: true }))
)
// 模板文件编译
const page = () => (
  src(pages, { base: configSrc, cwd: configSrc })
    .pipe(swig({ data, defaults: { cache: false } }))
    .pipe(dest(temp))
    .pipe(bs.reload({ stream: true }))
)
// 图片压缩
const image = () => (
  src(images, { base: configSrc, cwd: configSrc })
    .pipe(imagemin())
    .pipe(dest(dist))
)
// 字体压缩
const font = () => (
  src(fonts, { base: configSrc, cwd: configSrc })
    .pipe(imagemin())
    .pipe(dest(dist))
)
// public目录文件转换
const extra = () => (
  src('**', { base: configPublic, cwd: configPublic })
    .pipe(dest(dist))
)

// 文件引用处理及文件压缩
const use_ref = () => (
  src(pages, { base: temp, cwd: temp })
    .pipe(useref({ searchPath: [temp, '.', '..'] }))
    .pipe(gulp_if(/\.js$/, uglify()))
    .pipe(gulp_if(/\.css$/, cleanCss()))
    .pipe(gulp_if(/\.html$/, htmlmin({
      collapseWhitespace: true,
      minifyCSS: true,
      minifyJS: true
    })))
    .pipe(dest(dist))
)

// 热更新开发服务器
const serve = () => {
  watch(styles, { cwd: configSrc }, style) // 监听样式文件变化
  watch(scripts, { cwd: configSrc }, script) // 监听脚本文件变化
  watch(pages, { cwd: configSrc }, page) // 监听模板文件变化
  watch([
    images,
    fonts
  ], { cwd: configSrc }, bs.reload) // 监听图片和字体变化
  watch('**', { cwd: configPublic }, bs.reload) // 监听public文件目录文件变化
  // 初始化服务器
  bs.init({
    notify: false,
    port: 8888,
    server: {
      baseDir: [temp, configSrc, configPublic],
      routes: {
        '/node_modules': 'node_modules'
      }
    }
  })
}

// 组合构建任务
const compile = parallel(style, script, page)
const build = series(clean, parallel(series(compile, use_ref), extra, image, font))
const dev = series(compile, serve)

module.exports = {
  clean,
  build,
  dev
}